#include <QObject>

#include "rssfeed.h"
#include "definitions.h"


/*! \brief Sort by date aware widget item
	Only this class is allowed to be used in treeItems widget.
 */
class RssFeedItem : public QTreeWidgetItem
{
	public:
		RssFeedItem(const QString &feed, const QString &title, const QString &date, const QString &tooltip)
            : QTreeWidgetItem() {
			m_date = QDateTime::fromString(date, FEED_DATE_FORMAT);

			setText(0, title);

			// "clever" date dysplaying. For newer stuff display
			// day name and time only. For older use full date
			// time by app's locale
			if (m_date.date() > QDate::currentDate().addDays(-5))
				setText(1, m_date.toString("dddd hh:mm"));
			else
				setText(1, m_date.toString(Qt::DefaultLocaleShortDate));

			setText(2, feed);
			setToolTip(0, tooltip);
			setToolTip(1, tooltip);
			setToolTip(2, tooltip);
		}

		QDateTime date() const { return m_date; }

			bool operator<(const QTreeWidgetItem &other) const {
                // HACK. My eyes burn. But it should be fine as we use only RssFeedItem instances at all
                const RssFeedItem *i = reinterpret_cast<const RssFeedItem*>(&other);
                return date() < i->date();
            }

	private:
		QDateTime m_date;
};


RssFeed::RssFeed(const QString &title, const QString &link, const QString &cat,
				 RssgTypes::FeedType type, const QString &enc, const QNetworkReply::NetworkError &code) {
	this->title = title;
	this->link = link;
	this->cat = cat;
	if (enc.size())
		this->encoding = enc.toLocal8Bit();
	else
		this->encoding = "UTF-8";
	this->type = type;
	this->msgs = new QList<RssItem*>();
	this->state = code;
}

void RssFeed::trashMessages(bool onlySeen) {
	if (onlySeen) {
		// clear only seen messages
		foreach (RssItem* msg, *getMsgs()) {
			if (msg->isSeen())
				getMsgs()->removeOne(msg);
		}
	}
	else
		// clear all messages from this feed
		getMsgs()->clear();
}

void RssFeed::hideMessages(bool onlySeen) {
	foreach (RssItem* msg, *getMsgs()) {
		if (!onlySeen)
			msg->setHidden(true);
		else if (msg->isSeen())
			msg->setHidden(true);
	}
}

void RssFeed::unhideMessages() {
	foreach (RssItem *msg, *getMsgs())
		msg->setHidden(false);
}

void RssFeed::addMessage(const QString &title, const QString &link, const QString &description, const QString &date, bool seen, bool hidden) {
	getMsgs()->append(new RssItem(title, link, description, date, seen, hidden));
}

void RssFeed::markAllVisibleMessages(bool readUnread) {
	foreach (RssItem *msg, *getMsgs())
		if (!msg->isHidden())
			msg->setSeen(readUnread);
}

bool RssFeed::hasUnseenMessages() {
	foreach (RssItem *msg, *getMsgs())
		if (!msg->isSeen() && !msg->isHidden())
			return true;
	return false;
}

void RssFeed::updateRepresentation(QTreeWidget *widget, bool append) {
	if (!append)
		widget->clear();

	// Highlight unread item.
	QFont boldFont;
	boldFont.setBold(true);
	// Already read item.
	QFont regularFont;

	for (int i = getMsgs()->size() - 1; i >= 0; i--) {
		RssItem *rssItem = getMsgs()->at(i);
		if (rssItem->isHidden())
			continue;

		bool contained = false;

		QTreeWidgetItemIterator it(widget);
		while (*it) {
			if ((*it++)->toolTip(0) == rssItem->getLink()) {
				contained = true;
				break;
			}
		}

		if (contained)
			continue;

		QString messageTitle = rssItem->getTitle();
		if (messageTitle.size() > LIMIT_TRIM_MSG)
			messageTitle = messageTitle.left(LIMIT_TRIM_MSG) + "...";

		RssFeedItem *item = new RssFeedItem(getTitle(),
											messageTitle,
											rssItem->getDate(),
											rssItem->getLink());
		if (!getMsgs()->at(i)->isSeen()) {
			item->setFont(0, boldFont);
			item->setIcon(0, UiFactory::stateNewIcon);
		}
		else {
			item->setFont(0, regularFont);
			item->setIcon(0, UiFactory::stateNormalIcon);
		}
		widget->addTopLevelItem(item);
	}

	widget->resizeColumnToContents(1);
	widget->resizeColumnToContents(2);
	widget->sortByColumn(widget->sortColumn());
}

RssItem *RssFeed::getItemByLink(const QString &link) {
	foreach (RssItem *msg, *getMsgs())
		if (msg->getLink() == link)
			return msg;
	return NULL;
}
